#!/bin/bash

STEP_FIND_FILE_IMGS='find_file_imgs'
STEP_FIND_IMG_FILES='find_img_files'
STEP_IMG_USED_JUDGE='img_used_judge'
STEP_RM_IMG_FILE='rm_img_file'
help(){
    echo "img-clear.sh [options]"
    echo "  options:"
    echo "    -h/-? #帮助文档"
    echo "    -d 'dir' #指定目录查找，默认为当前目录"
    echo "    -i 'dir name' #指定图片目录名称，默认为'images'"
    echo "    -f 'file name' #指定文件名称，默认为'*.md'"
    echo "    -t #指定为测试模式"
    echo "    -x 'grep context' #指定输出信息过滤"
    echo "    -s 'stop step' #指定在哪个步骤停止"
    echo "    -ls 'log step' #指定只在哪个步骤时输出日志"
    echo "    -b #备份模式，删除图片时会将图片进行备份"
    echo "  steps:" 
    echo "    $STEP_FIND_FILE_IMGS #查找文件中使用的图片"
    echo "    $STEP_FIND_IMG_FILES #查找目录中存在的图片"
    echo "    $STEP_IMG_USED_JUDGE #图片是否使用判断"
    echo "    $STEP_RM_IMG_FILE #删除未使用的图片文件"
}
if [[ "$1" == "-h" || "$1" == "-?" ]]; then
    help
    exit 0
fi
empty(){
    if [[ -z "$1" || $1 == ^-* ]]; then
        echo "true"
    else
        echo "false"
    fi
}
end(){
    echo -e "\e[1;31;41m[Error]\e[0m $1"
    exit 0
}
end_if_empty(){
  e=`empty $1`
  if [[ "$e" == "true" ]]; then
    end "$2"
  fi
}

FIND_DIR=`pwd`
FIND_FILE_NAME='*.md'
FIND_IMG_DIR='images'
IS_TEST='false'
X_CONTENT=''
STOP_STEP=''
LOG_STEP=()
IS_BACKUP='false'
for (( i=1; i<=$#; i++ ));
do
    p=${@: $i:1}
    i=$(( $i + 1 ))
    v=${@: $i:1}
    case $p in
    "-d")
        end_if_empty "$v" "-d 需要目录。eg: -d ./test"
        FIND_DIR="$v"
      ;;&
    "-i")
        end_if_empty "$v" "-i 需要指当名称。eg: -i images"
        FIND_IMG_DIR="$v"
    ;;&
    "-f")
        end_if_empty "$v" "-f 需要指定文件名称。eg: -f test.md or -f *.md"
        FIND_FILE_NAME="$v"
    ;;&
    "-t")
        i=$(( $i - 1 ))
        v='true'
        IS_TEST="$v"
    ;;&
    "-x")
        end_if_empty "$v" "-x 需要指定过滤内容。eg: -x test"
        X_CONTENT="$X_CONTENT -e '$v'"
    ;;&
    "-s")
        end_if_empty "$v" "-s 需要指定停止模块。eg: -s find_file_name"     
        STOP_STEP="$v"
    ;;&
    "-ls")
        end_if_empty "$v" "-ls 需要指定跳转的输出日志步骤。eg: -ls find_file_name"
        LOG_STEP+=("$v")
    ;;&
    "-b")
        i=$(( $i - 1 ))
        v='true'
        IS_BACKUP="$v"
    ;;
    * )
        echo "config>> $p = $v"
    ;;
    esac
done
BACKUP_DIR='backup'
if [[ "$IS_BACKUP" == 'true' ]]; then
    if [[ ! -d "./$BACKUP_DIR" ]]; then
        mkdir ./$BACKUP_DIR
    fi
fi
info(){
    body="$1"
    skip='false'
    for skip in ${LOG_STEP[*]}; do
        if [[ "$body" =~ ^$skip.* ]]; then
           skip='true'
           break
        fi
    done
    if [[ "$skip" == 'true' ]]; then
        return
    fi
    color="${2:-0m}" 
    if [[ "$body" =~ "|-" ]]; then
        body="${body//\|-/\\e[$color}"
        body="${body//-\|/\\e[0m}"
    else
        body="\e[$color$body\e[0m"
    fi
    if [[ -z "$X_CONTENT" ]]; then
        echo -e "$body"  
    else
        cmd="echo -e '"$body"' | grep "$X_CONTENT" --color=auto"
        eval $cmd
    fi
}
tinfo(){
    if [[ "$IS_TEST" == "true" ]]; then
        info "$1" "$2"
    fi
}

declare -A FILE_USED_IMGS
declare -A FILE_FOLODERS
find_file_img(){
    file="$1"
    info "$STEP_FIND_FILE_IMGS find images used in |-$file-|" "1;33m"
    file_imgs=`grep -E "\!\[(.*.)?\]\(.*.\)" $1 |  sed -e 's|!\[*\]||g' -e 's|\n||g' -e 's|\r||g' | grep -e "(.*.)" -o | sed 's|(\(.*.\))|\1|g'`
    ffolder="${1%\/*}"
    num=FILE_FOLODERS["$ffolder"]
    if [[ -z "$num" ]]; then
        num=1
    else 
        num=$(( $num + 1 ))
    fi
    FILE_FOLODERS["$ffolder"]="$num"
    if [[ -z "$file_imgs" ]]; then
        info "$STEP_FIND_FILE_IMGS r――――→ |-not found!-|" "1;31m"
    else
        i=0
        for img in ${file_imgs}; do
            FILE_USED_IMGS["$img"]="$file"
            tinfo "$STEP_FIND_FILE_IMGS found |-$img-| used in |-$file-|" "1;33m"
            i=$(( $i + 1 ))
        done
        info "$STEP_FIND_FILE_IMGS r――――→ |-$i-| found" "1;34m"
    fi
}

stop_if(){
    if [[ -n "$STOP_STEP" && "$1" =~ "$STOP_STEP" ]]; then 
        info "stop at module |-$1-|" "1;31m"
        exit 0
    fi
}
FIND_FILES=`grep -l --include=$FIND_FILE_NAME . -r`
if [[ -z "$FIND_FILES" ]]; then
    end "not any file found!"
fi
for file in $FIND_FILES; do
	find_file_img $file
done
stop_if $STEP_FIND_FILE_IMGS

# at this time. all file used imgages saved to $FILE_USED_IMGS
# search all image files
FIND_IMG_FILES=($( find "$FIND_DIR" -type f -path "*$FIND_IMG_DIR*" ))
if [[ -z "$FIND_IMG_FILES" ]]; then
    end "not any image file found"
fi

rm_file(){
    if [[ "$IS_TEST" == "true" ]]; then 
        tinfo "$STEP_RM_IMG_FILE |-[test]-|: rm $1" "1;34m"
    else 
        info "$STEP_RM_IMG_FILE |-[remove]-|: $1" "1;31;31m"
        if [[ "$IS_BACKUP" == 'true' ]]; then
            mv $1 ./$BACKUP_DIR/${1//\//-} -f
        else
            rm $1 -rf
        fi
    fi
}

declare -A FIND_IMG_FILES_USED
info "$STEP_FIND_IMG_FILES find img file ${#FIND_IMG_FILES[*]} |-start-|" "1;33m"
for (( i=0; i<${#FIND_IMG_FILES[*]}; i++ )); do
    img_file="${FIND_IMG_FILES[$i]}"
    # 保证图片文件的目录是扫描的文件
    if [[ "$FIND_IMG_FILES_USED[$img_file]" == 'true' ]]; then
        continue
    fi
    skip='true'
    for file_folder in $(echo ${!FILE_FOLODERS[*]});
    do
        if [[ "$img_file" =~ "$file_folder" ]]; then
            skip='false'
            break
        fi
    done
    if [[ "$skip" == "true" ]]; then
        tinfo "$STEP_FIND_IMG_FILES $img_file |-skip-|" "1;36m"
        continue
    fi

    exist='false'
    for used_img in $(echo ${!FILE_USED_IMGS[*]});
    do
       if [[ "$img_file" =~ "$used_img" ]]; then
           exist='true'
           break
       fi  
    done
    FIND_IMG_FILES_USED["$img_file"]="$exist"
    tinfo "$STEP_FIND_IMG_FILES file $img_file exist:|-$exist-|" "1;33m"
done
stop_if $STEP_FIND_IMG_FILES


info "$STEP_IMG_USED_JUDGE count ${#FIND_IMG_FILES_USED[*]} |-start-|" "1;33m"
for find_img in $(echo ${!FIND_IMG_FILES_USED[*]}); do 
    exist="${FIND_IMG_FILES_USED[$find_img]}"
    tinfo "$STEP_IMG_USED_JUDGE $find_img |-$exist-|" "1;31m"
    if [[ "$exist" == "false" ]]; then 
       rm_file "$find_img"
    fi 
done 

info "done" "1;31;31m"
exit 0
